package com.aizhixin.lab.course.template.service;

import com.aizhixin.lab.config.Config;
import com.aizhixin.lab.course.template.domain.UploadResultDomain;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Component
public class UploadService {
    @Autowired
    private Config config;

    public UploadResultDomain uploadFile(String filename, InputStream inputStream) {
        UploadResultDomain result;
        if (getFileType(filename) == 0) {
            result = uploadPolyv(filename, inputStream);
        } else if (getFileType(filename) == 1) {
            result = uploadIO(filename, inputStream);
        } else {
            result = uploadQiniu(filename, inputStream);
        }
        return result;
    }

    private Configuration cfg = new Configuration(Region.autoRegion());
    private UploadManager uploadManager = new UploadManager(cfg);

    /**
     * @return
     */
    public String getUploadToken() {
        Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
        String upToken = auth.uploadToken(config.getBucket());
        return upToken;
    }
    public String getPolyvWriteToken(){

        return  config.getPolyvWriteToken();
    }
    public String getPolyvReadToken(){
        return config.getPolyvReadToken();
    }

    public String uploadFile(MultipartFile file) {
        String token = getUploadToken();
        try {
            String originalFilename = file.getOriginalFilename();
            // 文件后缀
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileKey = UUID.randomUUID().toString() + suffix;
            Response response = uploadManager.put(file.getInputStream(), fileKey, token, null, null);
            String domainOfBucket = config.getDomainOfBucket();
            return domainOfBucket + "/" + fileKey;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "error";
    }

    private int getFileType(String filename) {
        String office = "*.pdf;*.ppt;*.pptx;*.doc;*.docx;*.xls;*.xlsx;";
        String video = "*.flv,*.avi,*.mpg,*.mp4,*.wmv,*.mov,*.3gp,*.asf";
//        String pic = "*.jpg,*.jpeg,*.gif,*.png,*.bmp;";
        String suffix = filename.substring(filename.lastIndexOf(".")).toLowerCase();
        if (video.indexOf(suffix) > -1) {
            return 0;
        } else if (office.indexOf(suffix) > -1) {
            return 1;
        } else {
            return 2;
        }
    }

    /**
     * {
     * "key": "AD633782636748849A7FE91E81F2EB25",
     * "originalFileName": "www.easyicon.net.txt",
     * "extFileName": "txt",
     * "filePath": "default/bucket/2019-11-04/AD633782636748849A7FE91E81F2EB25.txt",
     * "ttl": null
     * }
     */
    private UploadResultDomain uploadIO(String filename, InputStream inputStream) {
        String token = getIOToken();
        if (token != null) {
            String appId = "aizhixinkaijuan";
            RestTemplate restTemplate = new RestTemplate();
            try {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.MULTIPART_FORM_DATA);

                Resource resource = new CommonInputStreamResource(inputStream, filename);
                MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
                params.add("file", resource);
                HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(params, headers);

                String queryPath = config.getUploadIOURL() + "?";
                queryPath += "appId=" + appId;
                queryPath += "&token=" + token;
                ResponseEntity<Map> response = restTemplate.postForEntity(queryPath, httpEntity, Map.class);
                log.info(String.valueOf(response.getBody()));
                if (response.getBody().get("key") != null) {
                    UploadResultDomain d = new UploadResultDomain();
                    d.setKey(response.getBody().get("key").toString());
                    d.setFilePath(response.getBody().get("filePath").toString());
                    return d;
                }
                return null;
            } catch (Exception e) {
                log.warn("Exception", e);
            }
        }
        return null;
    }

    /**
     * {
     * "token": "C3C56946A8DC4BB29DC91DC9BB4CDE5A"
     * }
     */
    private String getIOToken() {
        String appId = "aizhixinkaijuan";
        String appSecurity = "ACEF46E88656SWokjh6HB54";
        String auth = "YWl6aGl4aW5rYWlqdWFuOkFDRUY0NkU4ODY1NlNXb2tqaDZIQjU0";
        RestTemplate restTemplate = new RestTemplate();
        try {
            Map<String, Object> map = new HashMap<>();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(map, headers);
            String queryPath = config.getUploadIOToken() + "?";
            queryPath += "appId=" + appId;
            queryPath += "&appSecurity=" + appSecurity;
            queryPath += "&auth=" + auth;
            ResponseEntity<Map> response = restTemplate.postForEntity(queryPath, request, Map.class);
            log.info(String.valueOf(response.getBody()));
            if (response.getBody().get("token") != null) {
                return response.getBody().get("token").toString();
            }
            return null;
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return null;
    }

    private UploadResultDomain uploadPolyv(String filename, InputStream inputStream) {
        String token = getPolyvToken();
        if (token != null) {
            RestTemplate restTemplate = new RestTemplate();
            try {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.MULTIPART_FORM_DATA);

                Resource resource = new CommonInputStreamResource(inputStream, filename);
                MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
                params.add("Filedata", resource);
                params.add("writetoken", token);
                params.add("JSONRPC", "{\"title\":\"" + filename + "\"}");
                HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(params, headers);

                String queryPath = "http://v.polyv.net/uc/services/rest?method=uploadfile";
                ResponseEntity<Map> response = restTemplate.postForEntity(queryPath, httpEntity, Map.class);
                log.info(String.valueOf(response.getBody()));
                if (response.getBody().get("data") != null) {
                    List<Map<String, Object>> datas = (List<Map<String, Object>>) response.getBody().get("data");
                    if (datas != null) {
                        Map<String, Object> data = datas.get(0);
                        if (data != null && data.get("vid") != null) {
                            UploadResultDomain d = new UploadResultDomain();
                            d.setFilePath(data.get("vid").toString());
                            return d;
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("Exception", e);
            }
        }
        return null;
    }

    private String getPolyvToken() {
        RestTemplate restTemplate = new RestTemplate();
        try {
            String queryPath = config.getUploadPolyvToken();
            ResponseEntity<Map> response = restTemplate.getForEntity(queryPath, Map.class);
            log.info(String.valueOf(response.getBody()));
            if (response.getBody().get("token") != null) {
                return response.getBody().get("token").toString();
            }
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return null;
    }

    private UploadResultDomain uploadQiniu(String filename, InputStream inputStream) {
        String token = getQiniuToken();
        if (token != null) {
            RestTemplate restTemplate = new RestTemplate();
            try {
                String name = UUID.randomUUID() + filename.substring(filename.lastIndexOf("."));
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.MULTIPART_FORM_DATA);

                Resource resource = new CommonInputStreamResource(inputStream, name);
                MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
                params.add("file", resource);
                params.add("token", token);
                params.add("name", name);
                params.add("key", name);
                HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(params, headers);

                String queryPath = "http://upload.qiniup.com/";
                ResponseEntity<Map> response = restTemplate.postForEntity(queryPath, httpEntity, Map.class);
                log.info(String.valueOf(response.getBody()));
                if (response.getBody().get("key") != null) {
                    UploadResultDomain d = new UploadResultDomain();
                    d.setFilePath("https://s1.aizhixin.com/" + response.getBody().get("key").toString());
                    return d;
                }
            } catch (Exception e) {
                log.warn("Exception", e);
            }
        }
        return null;
    }

    private String getQiniuToken() {
        RestTemplate restTemplate = new RestTemplate();
        try {
            String queryPath = config.getUploadQiniuToken();
            ResponseEntity<Map> response = restTemplate.getForEntity(queryPath, Map.class);
            log.info(String.valueOf(response.getBody()));
            if (response.getBody().get("token") != null) {
                return response.getBody().get("token").toString();
            }
        } catch (Exception e) {
            log.warn("Exception", e);
        }
        return null;
    }
}
